package com.xunji.standard.util;

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * Excel工具类
 * 提供将实体列表导出为Excel文件的功能
 */
public class ExcelUtils {

    /**
     * 将实体列表导出为Excel文件
     *
     * @param dataList  实体对象列表
     * @param headers   表头数组（需与实体字段顺序对应）
     * @param sheetName 工作表名称
     * @param filePath  输出文件路径（包含文件名）
     * @param <T>       泛型类型，表示任意实体类
     * @throws IOException            文件读写异常
     * @throws IllegalAccessException 反射访问异常
     */
    public static <T> void exportToExcel(List<T> dataList, String[] headers,
                                         String sheetName, String filePath)
            throws IOException, IllegalAccessException {


        // 确保目录存在
        File file = new File(filePath);
        File parentDir = file.getParentFile();
        if (parentDir != null && !parentDir.exists()) {
            parentDir.mkdirs(); // 创建所有不存在的父目录
        }

        // 1. 创建工作簿和工作表
        try (Workbook workbook = new XSSFWorkbook()) {
            Sheet sheet = workbook.createSheet(sheetName);

            // 2. 创建表头样式（加粗、居中）
            CellStyle headerStyle = workbook.createCellStyle();
            Font headerFont = workbook.createFont();
            headerFont.setBold(true);
            headerStyle.setFont(headerFont);
            headerStyle.setAlignment(HorizontalAlignment.CENTER);
            headerStyle.setVerticalAlignment(VerticalAlignment.CENTER);

            headerStyle.setBorderTop(BorderStyle.THIN);
            headerStyle.setBorderBottom(BorderStyle.THIN);
            headerStyle.setBorderLeft(BorderStyle.THIN);
            headerStyle.setBorderRight(BorderStyle.THIN);
            headerStyle.setVerticalAlignment(VerticalAlignment.CENTER);

            // 3. 创建数据行样式（带边框）
            CellStyle dataStyle = workbook.createCellStyle();
            dataStyle.setBorderTop(BorderStyle.THIN);
            dataStyle.setBorderBottom(BorderStyle.THIN);
            dataStyle.setBorderLeft(BorderStyle.THIN);
            dataStyle.setBorderRight(BorderStyle.THIN);
            dataStyle.setVerticalAlignment(VerticalAlignment.CENTER);

            // 4. 创建表头行
            Row headerRow = sheet.createRow(0);
            for (int i = 0; i < headers.length; i++) {
                Cell cell = headerRow.createCell(i);
                cell.setCellValue(headers[i]);
                cell.setCellStyle(headerStyle);
                // 自动调整列宽
                sheet.autoSizeColumn(60);
                sheet.setColumnWidth(i, 20 * 256);
            }

            // 5. 填充数据行
            for (int i = 0; i < dataList.size(); i++) {
                Row row = sheet.createRow(i + 1);
                T item = dataList.get(i);
                Field[] fields = item.getClass().getDeclaredFields();

                for (int j = 0; j < fields.length; j++) {
                    fields[j].setAccessible(true);
                    Cell cell = row.createCell(j);
                    Object value = fields[j].get(item);
                    cell.setCellValue(value != null ? value.toString() : "");
                    cell.setCellStyle(dataStyle);
                }
            }

            // 6. 写入文件
            try (FileOutputStream fos = new FileOutputStream(filePath)) {
                workbook.write(fos);
            }
        }
    }

    /**
     * 示例用法
     */
    public static void main(String[] args) {
        // 示例数据
        ArrayList<Person> persons = new ArrayList<>();
        persons.add(new Person("张三张三张三张三张三张三", 18, "上海"));
        persons.add(new Person("李四李四李四李四李四李四李四", 19, "北京"));
        persons.add(new Person("王五李四李四李四李四李四李四李四李四李四李四李四", 20, "广州"));
        String[] headers = {"姓名", "年龄", "城市"};

        try {
            ExcelUtils.exportToExcel(persons, headers, "人员信息", "D:/test/persons.xlsx");
            System.out.println("Excel导出成功");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 示例实体类
    static class Person {
        private String name;
        private int age;
        private String city;

        public Person(String name, int age, String city) {
            this.name = name;
            this.age = age;
            this.city = city;
        }

        // 构造方法、getter/setter省略...
    }
}
